home *** CD-ROM | disk | FTP | other *** search
/ Mastering Computers 3 / Mastering Computers Vol 3.iso / Win95 / Fun&Utils / GLFONT.EXE / GLFONT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-31  |  13.8 KB  |  461 lines

  1. //****************************************************************************
  2. // File: glfont.c
  3. //
  4. // Purpose: Contains main message loop and application entry point.  Also contains
  5. //          the code to handle palettes properly in an OpenGL application and the
  6. //          main window callback procedure.
  7. //
  8. // Functions:
  9. //    WinMain - initializes everything and enters message loop
  10. //    InitializeWindow - Initializes the window class of and creates the main window
  11. //    MainWndProc - Main window procedure
  12. //    CommandHandler - Handle all WM_COMMAND messages
  13. //    ChangeFont - Allows the user to change the current TrueType font displayed.
  14. //
  15. // Development Team:
  16. //         Greg Binkerd - Windows Developer Support
  17. //
  18. // Written by Microsoft Windows Developer Support
  19. // Copyright (c) 1995 Microsoft Corporation. All rights reserved.
  20. //****************************************************************************
  21.  
  22. #include "glfont.h"
  23. #include "resource.h"
  24.  
  25. CHAR szAppName[]="GLFont";
  26.  
  27. HGLRC hRC;
  28.  
  29. HWND ghWnd;
  30. BOOL bDraw = TRUE;
  31.  
  32. extern HPALETTE ghpalOld, ghPalette;
  33.  
  34. /* forward declarations of helper functions in this module */
  35. HWND   WINAPI InitializeWindow (HINSTANCE, int);
  36. LONG   WINAPI CommandHandler (HWND, WPARAM, LPARAM);
  37. LONG   WINAPI MainWndProc (HWND, UINT, WPARAM, LPARAM);
  38. void   ChangeFont(HWND hWnd);
  39.  
  40.  
  41. //***********************************************************************
  42. // Function: WinMain
  43. //
  44. // Purpose: Called by Windows on app startup.  Initializes everything,
  45. //          and enters a message loop.
  46. //
  47. // Parameters:
  48. //    hInstance     == Handle to _this_ instance.
  49. //    hPrevInstance == Handle to last instance of app.
  50. //    lpCmdLine     == Command Line passed into app.
  51. //    nCmdShow      == How app should come up (i.e. minimized/normal)
  52. //
  53. // Returns: Return value from PostQuitMessage.
  54. //
  55. // Comments:
  56. //
  57. // History:  Date       Author        Reason
  58. //           6/08/94                  Created
  59. //****************************************************************************
  60.  
  61. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  62. {
  63.     MSG        msg;
  64.     HWND       hWnd;
  65.  
  66.     /* previous instances do not exist in Win32 */
  67.     if (hPrevInstance)
  68.         return 0;
  69.  
  70.     if (!(hWnd = InitializeWindow (hInstance, nCmdShow)))
  71.         return FALSE;
  72.  
  73.     /* main window message loop */
  74.     while (GetMessage (&msg, NULL, 0, 0))
  75.     {
  76.           TranslateMessage (&msg);
  77.           DispatchMessage (&msg);
  78.     }
  79.  
  80.     /* return success of application */
  81.     return TRUE;
  82. }
  83.  
  84.  
  85. //****************************************************************************
  86. // Function: InitializeWindow
  87. //
  88. // Purpose: Called by WinMain on first instance of app.  Registers
  89. //          the window class.
  90. //
  91. // Parameters:
  92. //    hInstance == Handle to _this_ instance.
  93. //    nCmdShow  == Initial state of window
  94. //
  95. // Returns: Handle to newly created window if successful
  96. //
  97. // Comments:
  98. //
  99. // History:  Date       Author        Reason
  100. //           5/30/95                  Modified
  101. //****************************************************************************
  102.  
  103. HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow)
  104.     {
  105.     WNDCLASS   wc;
  106.     HWND       hWnd;
  107.  
  108.     /* Register the frame class */
  109.     wc.style         = 0;
  110.     wc.lpfnWndProc   = (WNDPROC)MainWndProc;
  111.     wc.cbClsExtra    = 0;
  112.     wc.cbWndExtra    = 0;
  113.     wc.hInstance     = hInstance;
  114.     wc.hIcon         = LoadIcon (hInstance, szAppName);
  115.     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
  116.     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  117.     wc.lpszMenuName  = szAppName;
  118.     wc.lpszClassName = szAppName;
  119.  
  120.     if (!RegisterClass (&wc) )
  121.         return FALSE;
  122.  
  123.     /* Create the frame */
  124.     ghWnd = hWnd = CreateWindow (szAppName,
  125.              "wglUseFontOutlines OpenGL Sample",
  126.          WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
  127.              CW_USEDEFAULT,
  128.              CW_USEDEFAULT,
  129.              CW_USEDEFAULT,
  130.              CW_USEDEFAULT,
  131.              NULL,
  132.              NULL,
  133.              hInstance,
  134.              NULL);
  135.  
  136.     /* make sure window was created */
  137.     if (!hWnd)
  138.         return FALSE;
  139.  
  140.     /* show and update main window */
  141.     ShowWindow (hWnd, nCmdShow);
  142.  
  143.     UpdateWindow (hWnd);
  144.  
  145.     return hWnd;
  146. }
  147.  
  148.  
  149. //****************************************************************************
  150. // Function: MainWndProc
  151. //
  152. // Purpose: Message handler for main overlapped window.
  153. //
  154. // Parameters:
  155. //    hWnd    == Handle to this window.
  156. //    uMsg    == Message to process.
  157. //    wParam  == WORD parameter -- depends on message
  158. //    lParam  == LONG parameter -- depends on message
  159. //
  160. // Returns: Depends on message.
  161. //
  162. // Comments:
  163. //
  164. // History:  Date       Author        Reason
  165. //           3/30/95    GGB           Modified
  166. //****************************************************************************
  167.  
  168. LONG WINAPI MainWndProc (
  169.     HWND    hWnd,
  170.     UINT    uMsg,
  171.     WPARAM  wParam,
  172.     LPARAM  lParam)
  173. {
  174.     LONG    lRet = 1;
  175.     UINT    nTimer;
  176.  
  177.     switch (uMsg)
  178.     {
  179.       case WM_CREATE:
  180.             {
  181.             HDC     hDC;
  182.             LOGFONT     lf;
  183.             HFONT       hFont, hOldFont;
  184.             GLYPHMETRICSFLOAT agmf[256];
  185.  
  186.             hDC = GetDC(hWnd);
  187.             bSetupPixelFormat(hDC);
  188.  
  189.             hRC = wglCreateContext( hDC );
  190.             wglMakeCurrent( hDC, hRC );
  191.  
  192.             // Let's create a default TrueType font to display.
  193.             memset(&lf,0,sizeof(LOGFONT));
  194.             lf.lfHeight               =   -28 ;
  195.             lf.lfWeight               =   FW_NORMAL ;
  196.             lf.lfCharSet              =   ANSI_CHARSET ;
  197.             lf.lfOutPrecision         =   OUT_DEFAULT_PRECIS ;
  198.             lf.lfClipPrecision        =   CLIP_DEFAULT_PRECIS ;
  199.             lf.lfQuality              =   DEFAULT_QUALITY ;
  200.             lf.lfPitchAndFamily       =   FF_DONTCARE|DEFAULT_PITCH;
  201.             lstrcpy (lf.lfFaceName, "Arial") ;
  202.  
  203.             hFont = CreateFontIndirect(&lf);
  204.             hOldFont = SelectObject(hDC,hFont);    
  205.  
  206.             // Create a set of display lists based on the glyphs of the TT font we selected 
  207.             if (!(wglUseFontOutlines(hDC, 0, 255, GLF_START_LIST, 0.0f, 0.15f, 
  208.                WGL_FONT_POLYGONS, agmf)))
  209.                  MessageBox(hWnd,"wglUseFontOutlines failed!","GLFont",MB_OK);
  210.             
  211.             DeleteObject(SelectObject(hDC,hOldFont));    
  212.  
  213.             // Set timer to animate the text
  214.             nTimer =  SetTimer(hWnd, 0,    50,    NULL);
  215.             break;
  216.             }
  217.  
  218.         case WM_TIMER:
  219.             // If ready and not iconized, draw the text.
  220.             if ((bDraw) && (!(IsIconic(hWnd))))
  221.                draw_scene(hWnd);
  222.             break;
  223.  
  224.         case WM_SIZE:
  225.             resize(hWnd);
  226.             DefWindowProc (hWnd, uMsg, wParam, lParam);
  227.             break;
  228.  
  229.         // The WM_QUERYNEWPALETTE message informs a window that it is about to
  230.         // receive input focus. In response, the window receiving focus should
  231.         // realize its palette as a foreground palette and update its client
  232.         // area. If the window realizes its palette, it should return TRUE;
  233.         // otherwise, it should return FALSE.
  234.  
  235.         case WM_QUERYNEWPALETTE:
  236.         {
  237.             HDC     hDC;
  238.  
  239.             if(ghPalette)
  240.             {
  241.                 hDC = GetDC(hWnd);
  242.  
  243.                 // Select and realize the palette
  244.  
  245.                 ghpalOld = SelectPalette(hDC, ghPalette, FALSE);
  246.                 RealizePalette(hDC);
  247.  
  248.                 // Redraw the client area
  249.  
  250.                 InvalidateRect(hWnd, NULL, TRUE);
  251.                 UpdateWindow(hWnd);
  252.  
  253.                 if(ghpalOld)
  254.                     SelectPalette(hDC, ghpalOld, FALSE);
  255.  
  256.                 ReleaseDC(hWnd, hDC);
  257.  
  258.                 return TRUE;
  259.             }
  260.  
  261.             return FALSE;
  262.         }
  263.  
  264.         // The WM_PALETTECHANGED message informs all windows that the window
  265.         // with input focus has realized its logical palette, thereby changing 
  266.         // the system palette. This message allows a window without input focus
  267.         // that uses a color palette to realize its logical palettes and update
  268.         // its client area.
  269.         //
  270.         // This message is sent to all windows, including the one that changed
  271.         // the system palette and caused this message to be sent. The wParam of
  272.         // this message contains the handle of the window that caused the system
  273.         // palette to change. To avoid an infinite loop, care must be taken to
  274.         // check that the wParam of this message does not match the window's
  275.         // handle.
  276.  
  277.         case WM_PALETTECHANGED:
  278.         {
  279.             HDC         hDC; 
  280.  
  281.             // Before processing this message, make sure we
  282.             // are indeed using a palette
  283.  
  284.             if (ghPalette)
  285.             {
  286.                 // If this application did not change the palette, select
  287.                 // and realize this application's palette
  288.  
  289.                 if (wParam != (WPARAM)hWnd)
  290.                 {
  291.                     // Need the window's DC for SelectPalette/RealizePalette
  292.  
  293.                     hDC = GetDC(hWnd);
  294.  
  295.                     // Select and realize our palette
  296.  
  297.                     ghpalOld = SelectPalette(hDC, ghPalette, FALSE);
  298.                     RealizePalette(hDC);
  299.  
  300.                     // WHen updating the colors for an inactive window,
  301.                     // UpdateColors can be called because it is faster than
  302.                     // redrawing the client area (even though the results are
  303.                     // not as good)
  304.  
  305.                     UpdateColors(hDC);
  306.  
  307.                     // Clean up
  308.  
  309.                     if (ghpalOld)
  310.                        SelectPalette(hDC, ghpalOld, FALSE);
  311.  
  312.                     ReleaseDC(hWnd, hDC);
  313.                 }
  314.             }
  315.             break;
  316.         }
  317.  
  318.         case WM_COMMAND:
  319.             lRet = CommandHandler (hWnd, wParam, lParam);
  320.             break;
  321.  
  322.            case WM_CLOSE:
  323.             {
  324.                  /* call destroy window to cleanup and go away */
  325.             DestroyWindow (hWnd);
  326.             }
  327.             break;
  328.  
  329.            case WM_DESTROY:
  330.             {
  331.             HGLRC    hRC;
  332.             HDC      hDC;
  333.  
  334.               // Clean up timer and display lists
  335.               KillTimer(hWnd,nTimer);
  336.             glDeleteLists(GLF_START_LIST, 256);
  337.  
  338.             /* release and free the device context and rendering context */
  339.             hRC = wglGetCurrentContext();
  340.             hDC = wglGetCurrentDC();
  341.  
  342.             wglMakeCurrent(NULL, NULL);
  343.  
  344.             if (hRC)
  345.                   wglDeleteContext(hRC);
  346.             if (hDC)
  347.                 ReleaseDC(hWnd, hDC);
  348.             PostQuitMessage (0);
  349.             }
  350.             break;
  351.  
  352.         default:
  353.             /* pass all unhandled messages to DefWindowProc */
  354.             lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
  355.         break;
  356.     }
  357.  
  358.     /* return 1 if handled message, 0 if not */
  359.     return lRet;
  360. }
  361.  
  362.  
  363. //****************************************************************************
  364. // Function: CommandHandler
  365. //
  366. // Purpose: Command handler for main overlapped window.
  367. //
  368. // Parameters:
  369. //    hWnd    == Handle to this window.
  370. //    wParam  == WORD parameter -- depends on message
  371. //    lParam  == LONG parameter -- depends on message
  372. //
  373. // Returns: Depends on message.
  374. //
  375. // Comments:
  376. //
  377. // History:  Date       Author        Reason
  378. //           3/15/95                  Created
  379. //****************************************************************************
  380.  
  381. LONG WINAPI CommandHandler (
  382.     HWND    hWnd,
  383.     WPARAM  wParam,
  384.     LPARAM  lParam)
  385. {
  386.     switch (LOWORD(wParam))
  387.     {
  388.         case IDM_EXIT:
  389.             /* exit application */
  390.             PostMessage (hWnd, WM_CLOSE, 0, 0L);
  391.             break;
  392.  
  393.         case ID_CHANGEFONT:
  394.               ChangeFont(hWnd);
  395.               break;
  396.         
  397.         default:
  398.             return FALSE;
  399.     }
  400.     return TRUE;
  401. }
  402.  
  403.  
  404. //****************************************************************************
  405. // Function: ChangeFont
  406. //
  407. // Purpose: Allows the user to change the TrueType font that is displayed
  408. //          in the main window.  If the user selects a new font, this function
  409. //          will delete the display lists for the old font and create a new
  410. //          set of display lists for the new font with wglUseFontOutlines
  411. //
  412. // Parameters:
  413. //    hWnd    == Handle to this window.
  414. //
  415. // Returns: void
  416. //
  417. // Comments:
  418. //
  419. // History:  Date       Author        Reason
  420. //           5/31/95    GGB           Created
  421. //****************************************************************************
  422.  
  423. void ChangeFont(HWND hWnd)
  424. {
  425.    CHOOSEFONT    chf;
  426.    HDC           hDC;
  427.    LOGFONT       lf;
  428.    HFONT         hFont, hOldFont;
  429.    GLYPHMETRICSFLOAT agmf[256];
  430.  
  431.    
  432.    // Don't draw while we are doing this.
  433.    bDraw = FALSE;
  434.    // Erase what is currently on the window
  435.    InvalidateRect(hWnd,NULL,TRUE);
  436.    // Fill in the CHOOSEFONT structure
  437.    memset(&chf,0,sizeof(CHOOSEFONT));
  438.    chf.lStructSize = sizeof(CHOOSEFONT);
  439.    chf.hwndOwner = hWnd;
  440.    chf.lpLogFont = &lf;
  441.    chf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_TTONLY;
  442.    chf.nFontType = SCREEN_FONTTYPE;
  443.  
  444.    if (ChooseFont( &chf )) 
  445.        {
  446.        // Delete the current font's display lists
  447.        glDeleteLists(GLF_START_LIST, 256);
  448.        hDC = wglGetCurrentDC();
  449.        hFont = CreateFontIndirect(&lf);
  450.        hOldFont = SelectObject(hDC,hFont);    
  451.  
  452.        // Create a set of display lists based on the glyphs of the TT font selected 
  453.        if (!(wglUseFontOutlines(hDC, 0, 255, GLF_START_LIST, 0.0f, 0.15f, 
  454.             WGL_FONT_POLYGONS, agmf)))
  455.              MessageBox(hWnd,"wglUseFontOutlines failed!","GLFont",MB_OK);
  456.        DeleteObject(SelectObject(hDC,hOldFont));    
  457.        InvalidateRect(hWnd,NULL,TRUE); 
  458.        }
  459.    bDraw = TRUE;
  460. }
  461.